package sg.edu.nus.iss.cerberus.engine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;

import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;

import sg.edu.nus.iss.cerberus.model.CClass;
import sg.edu.nus.iss.cerberus.model.CConstructor;
import sg.edu.nus.iss.cerberus.model.CMemberMethod;
import sg.edu.nus.iss.cerberus.model.CMemberVariable;
import sg.edu.nus.iss.cerberus.model.CPackage;
import sg.edu.nus.iss.cerberus.util.CerberusConstants;

import sg.edu.nus.iss.cerberus.util.CerberusMethodsDelegate;

/**
 * @author  Priyanka (a0065715)
 * @author Lin
 * 
 * */

public class TestEngineObjectCreator implements ITestEngineObjectsCreator {

	public CPackage createCPackage(IPackageFragment mypackage) {
		CPackage cpack = null;
		if (mypackage != null && mypackage.getElementName() == "")
			cpack = new CPackage(mypackage.getElementName().toString(), null);
		return cpack;

	}

	public CClass createCCLass(AbstractTypeDeclaration type,
			HashMap<String, ArrayList<CMemberMethod>> methodHash,
			ArrayList<CMemberVariable> fieldArray,
			ArrayList<CConstructor> constructorArray) {
		if (type != null && methodHash != null && fieldArray != null
				&& constructorArray != null)
			return new CClass(
					type.getName().toString(),
					methodHash,
					CerberusMethodsDelegate.modifierMapper(type.getModifiers()),
					fieldArray, constructorArray);
		else
			return null;
	}

	public CMemberVariable createCField(FieldDeclaration field) {
		String variableName = null;
		Object val = null;
		if (field != null) {
			List list = new ArrayList();
			list = field.fragments();
			if (list.size() > 0) {
				for (int i = 0; i < list.size(); i++) {
					StringTokenizer token = new StringTokenizer(list.get(i)
							.toString(), "=;");

					variableName = token.nextToken();
					// Bug Fix - Lin
					if (token.hasMoreTokens()) {
						val = token.nextToken();
					}
				}
			}
			return new CMemberVariable(
					CerberusMethodsDelegate
							.modifierMapper(field.getModifiers()),
					field.getType().toString(), variableName, val);
		}
		return null;
	}

	public CMemberMethod createCMethod(MethodDeclaration method) {

		if (method != null) {
			ArrayList<String> methodParams = new ArrayList<String>();
			List list = new ArrayList();
			list = (List) method.parameters();
			if (list.size() > 0) {

				// get the type only here
				for (int i = 0; i < list.size(); i++) {
					StringTokenizer token = new StringTokenizer(list.get(i)
							.toString(), "=;");
					methodParams.add(token.nextToken());

				}

				return new CMemberMethod(
						CerberusMethodsDelegate.modifierMapper(method
								.getModifiers()), method.getReturnType2()
								.toString(), method.getName()
								.getFullyQualifiedName(), methodParams);
			} else {

				return new CMemberMethod(
						CerberusMethodsDelegate.modifierMapper(method
								.getModifiers()), method.getReturnType2()
								.toString(), method.getName()
								.getFullyQualifiedName(), null);
			}
		} else
			return null;
	}

	public CConstructor createCConstructor(MethodDeclaration method) {
		ArrayList<String> methodParams = null;
		if (method != null) {
			List list = new ArrayList();
			list = (List) method.parameters();
			if (list.size() > 0) {
				methodParams = new ArrayList<String>();
				// get the type only here
				for (int i = 0; i < list.size(); i++) {
					StringTokenizer token = new StringTokenizer(list.get(i)
							.toString(), "=;");
					methodParams.add(token.nextToken());

				}
				//normal Constructor
				return new CConstructor(CerberusMethodsDelegate.modifierMapper(method
						.getModifiers()), method.getName().toString(),
				methodParams, false);
			}
			//Default Constructor
			return new CConstructor(
					CerberusMethodsDelegate.modifierMapper(method
							.getModifiers()), method.getName().toString(),
					methodParams, true);
		}else
			return null;
		
	}
}
